﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.WebControls;
using System.Collections;
using Microsoft.SharePoint;

namespace CustomFieldTypes.SharePointRoot.Template.ControlTemplates
{
    public partial class TableCheckFieldControl : BaseFieldControl
    {
        #region Properties
        private TableCheckField ParentField;

        private Table tbValues;
        private Label lblHeader1Name;
        private Label lblHeader2Name;
        private Label lblHeader3Name;

        private Dictionary<string, ControlSet> tableControlsList = new Dictionary<string,ControlSet>();
        #endregion

        #region Constructors
        public TableCheckFieldControl(TableCheckField parentField)
        { this.ParentField = parentField; } 
        #endregion

        protected override string DefaultTemplateName
        {
            get
            {
                if (this.ControlMode == SPControlMode.Display)
                {
                    return this.DisplayTemplateName;
                }
                else
                {
                    return "TableCheckFieldControlTemplate";
                }
            }
        }

        /// <summary>
        /// This override can be replaced to return a defferent temaplte name which can 
        /// also reside in the ascx file under 
        /// <SharePoint:RenderingTemplate ID="TableCheckFieldControlTemplateForDisplay" runat="server">
        /// for my purpose I will use the same template
        /// </summary>
        public override string DisplayTemplateName
        {
            get
            {
                return "TableCheckFieldControlTemplate";
            }
            set
            {
                base.DisplayTemplateName = value;
            }
        }

        protected override void CreateChildControls()
        {
            if (this.Field != null)
            {
                // Make sure inherited child controls are completely rendered.
                base.CreateChildControls();

                // Associate child controls in the .ascx file with the 
                // fields allocated by this control.
                this.tbValues = (Table)TemplateContainer.FindControl("tbValues");
                this.lblHeader1Name = (Label)TemplateContainer.FindControl("lblHeader1Name");
                this.lblHeader2Name = (Label)TemplateContainer.FindControl("lblHeader2Name");
                this.lblHeader3Name = (Label)TemplateContainer.FindControl("lblHeader3Name");

                bool editMode = (this.ControlMode == SPControlMode.Edit);
                bool newMode = (this.ControlMode == SPControlMode.New);

                if (!Page.IsPostBack)
                {
                    lblHeader1Name.Text = this.ParentField.Header1Name;
                    lblHeader2Name.Text = this.ParentField.Header2Name;
                    lblHeader3Name.Text = this.ParentField.Header3Name;
                }

                // Assign current value from database to the label control
                // Value 1|true|login|User Name; Value 2|true|login|User Name;
                var listValues = this.ParentField.ValuesList.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                var selectedValues = TableCheckFieldValue.FromFieldValue(string.Empty + this.ItemFieldValue);
                int idIndex = 1;
                foreach (var listValue in listValues)
                {
                    var formattedValue = listValue.Trim();
                    var selectedValue = selectedValues.FirstOrDefault(val => val.Name == formattedValue) ?? new TableCheckFieldValue();

                    TableRow valueRow = new TableRow();
                    tbValues.Rows.Add(valueRow);

                    TableCell titleCell = new TableCell();
                    valueRow.Cells.Add(titleCell);
                    titleCell.Text = formattedValue;

                    TableCell checkCell = new TableCell();
                    valueRow.Cells.Add(checkCell);

                    // Creating a checkbox to check the default option
                    CheckBox chkSelected = new CheckBox();
                    chkSelected.ID = "chkSelected" + idIndex.ToString();
                    chkSelected.Attributes["DisplayName"] = formattedValue;
                    chkSelected.Enabled = editMode || newMode;
                    checkCell.Controls.Add(chkSelected);

                    chkSelected.Checked = selectedValue.Checked;

                    TableCell representativeCell = new TableCell();
                    valueRow.Cells.Add(representativeCell);

                    // Creating the people editor and populating with the selected field
                    PeopleEditor peSelectedRepresentative = new PeopleEditor();
                    peSelectedRepresentative.ID = "peSelectedRepresentative" + idIndex.ToString();
                    peSelectedRepresentative.SelectionSet = "User";
                    peSelectedRepresentative.MultiSelect = false;
                    peSelectedRepresentative.Width = new Unit("250px");
                    peSelectedRepresentative.Attributes["DisplayName"] = formattedValue;
                    peSelectedRepresentative.Enabled = editMode || newMode;
                    representativeCell.Controls.Add(peSelectedRepresentative);

                    peSelectedRepresentative.CommaSeparatedAccounts = selectedValue.Login;
                    peSelectedRepresentative.Validate();

                    // Adding to control searchable collection
                    tableControlsList.Add(formattedValue, new ControlSet
                        {
                            CheckBox = chkSelected,
                            PeopleEditor = peSelectedRepresentative
                        });

                    idIndex++;
                }

            }// end if there is a non-null underlying ISBNField 

            // Do nothing if the ISBNField is null.
        }

        private string GetFieldControlValue()
        {
            var allValues = new List<TableCheckFieldValue>();
            foreach (var valueName in tableControlsList.Keys)
            {
                if (tableControlsList[valueName].CheckBox.Checked ||
                    !string.IsNullOrEmpty(tableControlsList[valueName].PeopleEditor.CommaSeparatedAccounts))
                {
                    var entity = FirstOrDefault(tableControlsList[valueName].PeopleEditor);
                    allValues.Add(new TableCheckFieldValue
                        {
                            Name = valueName,
                            Checked = tableControlsList[valueName].CheckBox.Checked,
                            Login = entity.Key,
                            UserName = entity.EntityData["DisplayName"].ToString()
                        });
                }
            }

            return TableCheckFieldValue.ToFieldValue(allValues);
        }

        private PickerEntity FirstOrDefault(PeopleEditor peopleEditor)
        {
            peopleEditor.Validate();
            if (peopleEditor.Entities.Count == 0)
            {
                var newPickerEntity = new PickerEntity();
                newPickerEntity.Key = string.Empty;
                newPickerEntity.EntityData = new Hashtable();
                newPickerEntity.EntityData["DisplayName"] = string.Empty;
                return newPickerEntity;
            }

            var entity = (PickerEntity)peopleEditor.Entities[0];
            if (entity.EntityData["DisplayName"] == null)
            {
                try
                {
                    int userID = int.Parse(entity.EntityData["SPUserID"].ToString());
                    var user = SPContext.Current.Web.Users.GetByID(userID);
                    entity.EntityData["DisplayName"] = user.Name;
                }
                catch
                {
                    entity.EntityData["DisplayName"] = entity.Key;
                }
            }
            return entity;
        }

        //get/set value for custom field 
        public override object Value
        {
            get
            {
                return GetFieldControlValue();
            }
            set { }
        }

        //Update field value with user input & check field validation
        public override void UpdateFieldValueInItem()
        {
            this.EnsureChildControls();
            try
            {
                this.Value = GetFieldControlValue();
                this.ItemFieldValue = GetFieldControlValue();
            }

            catch (Exception ex)
            {
                this.IsValid = false;
                this.ErrorMessage = "* " + ex.Message;
            }
        }


        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (this.ControlMode == SPControlMode.Edit ||
                this.ControlMode == SPControlMode.New)
            { /* Code to run in input mode */ }
        }
    }
}